package cn.mugutu.finance.service.system.impl;

import cn.mugutu.finance.domain.system.Department;
import cn.mugutu.finance.domain.system.Log;
import cn.mugutu.finance.domain.system.Role;
import cn.mugutu.finance.domain.system.User;
import cn.mugutu.finance.dto.BaseResult;
import cn.mugutu.finance.vo.UserAddReqVO;
import cn.mugutu.finance.service.system.LogService;
import cn.mugutu.finance.service.system.RoleService;
import cn.mugutu.finance.service.system.UserService;
import cn.mugutu.finance.utils.ConstantConfig;
import cn.mugutu.finance.utils.EncryptUtil;
import cn.mugutu.finance.enums.LogTyep;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements UserService {

    @Autowired
    private RoleService roleService;
    @Autowired
    private LogService logService;

    public BaseResult login(String username, String password, String randomcode, HttpServletRequest request) {
        String validateCode = (String) request.getSession().getAttribute("validateCode");
        if (StringUtils.isBlank(validateCode)) {
            return new BaseResult(false, "验证码已经失效,请重新登陆");
        }
        if (!randomcode.equals(validateCode)) {
            return new BaseResult(false, "验证码错误");
        }

        List<User> list = findByHql("FROM User u WHERE u.username = ? ", username);
        User user = null;
        if (list.size() != 1) {
            return new BaseResult(false, "用户名不存在");
        } else {
            user = list.get(0);
            if (!EncryptUtil.md5Encrypt(password).equals(user.getPassword())) {
                return new BaseResult(false, "密码错误");
            }
            if (user.isLocked()) {
                return new BaseResult(false, "账号:[" + username + "]已经被锁定,请联系管理员.");
            }
        }
        HttpSession session = request.getSession();
        session.setAttribute(ConstantConfig.USER_IN_SESSION, user);

        //登陆成功后清除session验证码,防止用户后退重复登陆
        session.removeAttribute("validateCode");
        Date now = new Date();
        user.setLastLoginDate(user.getLoginDate());
        user.setLoginDate(now);
        user.setLastLoginIp(user.getLoginIp());
        user.setLoginIp(request.getRemoteHost());

        //向在线用户统计中添加一条在线用户上线的记录
        checkAccountIsAlreadyLogin(request, user);

        //记录一条登陆日志
        Log log = new Log();
        log.setUserId(user.getId());
        log.setUsername(username + "/" + user.getRealname());
        log.setMethods("login");
        log.setRequestIp(request.getRemoteAddr());
        log.setOperTime(now);
        log.setDescription("登陆进入系统.");
        log.setLogTyep(LogTyep.BUSINESSLOG);  //异常日志
        logService.save(log);

        return new BaseResult(true, "登陆成功");
    }

    //检查是不是同一个账号同时第二次登陆
    public void checkAccountIsAlreadyLogin(HttpServletRequest request, User user) {
        Map<String, HttpSession> onlineUsers = (Map<String, HttpSession>) request.getSession().getServletContext().getAttribute(
                ConstantConfig.ONLINE_USER_LIST);
        if (onlineUsers == null) {
            onlineUsers = new HashMap<>();
        }
        HttpSession oldSession = onlineUsers.get(user.getUsername());  //这里的username是唯一的
        if (oldSession != null) {
            //前面已经有人用该账号登陆了,挤掉
            oldSession.invalidate();
        }
        //缓存现在的
        onlineUsers.put(user.getUsername(), request.getSession());
        request.getSession().getServletContext().setAttribute(ConstantConfig.ONLINE_USER_LIST, onlineUsers);
    }

    @Override
    public BaseResult updatePassword(String oldPassword, String newPassword, String confirmPassword, User loginUser) {
        if (!newPassword.equals(confirmPassword)) {
            return new BaseResult(false, "两次输入的密码不一致.");
        }
        if (!EncryptUtil.md5Encrypt(oldPassword).equals(loginUser.getPassword())) {
            return new BaseResult(false, "输入旧密码错误.");
        }

        loginUser.setPassword(EncryptUtil.md5Encrypt(newPassword));
        update(loginUser);

        return new BaseResult(true, "修改成功");
    }

    @Override
    public BaseResult lockUser(Long id) {
        if (id == null) {
            return new BaseResult(false, "操作失败");
        }
        User user = get(id);
        if (user == null) {
            return new BaseResult(false, "操作失败");
        }

        if (user.isLocked()) {
            user.setLocked(false);
        } else {
            user.setLocked(true);
        }
        update(user);
        return new BaseResult(true, "操作成功.");
    }

    @Override
    public List<String> findSysResourceByLoginUser(User user) {
        return findByHql("select distinct res.code from User u "
                + "	join u.roles r join r.resources res where u=?", user);
    }

    @Override
    public BaseResult saveOrUpdateUser(UserAddReqVO userAddReqVO) {
        if (userAddReqVO.getId() != null) {
            User oldUser = get(userAddReqVO.getId());
            if ("admin".equals(oldUser.getUsername())) {
                return new BaseResult(false, "超级管理员账户不能修改.");
            }
            oldUser.setUsername(userAddReqVO.getUsername());
            oldUser.setRealname(userAddReqVO.getRealname());

            //添加部门
            if (userAddReqVO.getDepartmentId() != null) {
                Department department = new Department();
                department.setId(userAddReqVO.getDepartmentId());
                oldUser.setDepartment(department);
            }

            //添加角色
            Set<Long> roleIds = userAddReqVO.getRoleIds();
            Set<Role> roles = new HashSet<>();
            if (roleIds != null) {
                oldUser.setRoles(null);
                for (Long roleId : roleIds) {
                    Role role = roleService.get(roleId);
                    roles.add(role);
                }
            }
            oldUser.setRoles(roles);

            update(oldUser);
            return new BaseResult(true, "修改成功");
        } else {
            //判断username已经存在
            if (usernameIsExist(userAddReqVO.getUsername())) {
                return new BaseResult(false, "该登陆名已经存在,请重新输入,建议采用用户名的拼音作为登陆名.");
            }
            User user = new User();
            user.setUsername(userAddReqVO.getUsername());
            user.setRealname(userAddReqVO.getRealname());

            //添加部门
            Department department = new Department();
            department.setId(userAddReqVO.getDepartmentId());
            user.setDepartment(department);

            //添加角色
            Set<Long> roleIds = userAddReqVO.getRoleIds();
            for (Long roleId : roleIds) {
                Role role = roleService.get(roleId);
                user.getRoles().add(role);
            }

            user.setCreateDate(new Date());
            user.setPassword(EncryptUtil.md5Encrypt(ConstantConfig.DEFAULT_PASSWORD));
            user.setLastLoginDate(new Date());
            save(user);
            return new BaseResult(true, "新增成功");
        }
    }

    @Override
    public boolean usernameIsExist(String username) {
        List list = findByHql("FROM User o WHERE o.username = ? ", username);
        if (list != null && list.size() > 0) {
            return true;
        }
        return false;
    }

}
